#lang racket

(require "primitives.rkt")

(define ssh-host "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEgoOCvxbeU3bwMpYeglV7fZx2I5CdGmzcA62rYFuMHhaghyWLazXHd3D356YWJVj0ZLTb8T/YEqglQ8Yqd7rM0acqyiZyajO5sGLqEk7R7m1q1nF/hHq5OG3v/5SKBTg64GMFm6V60D67LU493sIdpH+axwr6PVoKEQYiBigBgAhqYhtL2WtTtABhtMT6149ccJo7pJ5entQOg/RKuhT+9VMmPt3H66rvInloUkBeggrpRidsSwb6+YSVIQME3FPqWdE3k61FHicTyRryWfoxes/TR4azbqMn1BeTmYPqpiUTDfxgPnWEoOYiR5NfnqPzi9yZOTcu6ouFj73N4TqJ")

(define ssh-key
  "-----BEGIN DSA PRIVATE KEY-----
MIIBugIBAAKBgQDBH3b05clpYlaiSV5pnYsjSfGxuOAciLQF4od7ZUnyu5A2TOKT
41HTY5Vpx+DjxK82VgMW151VEvbMdFNt2n+hnVHfNATkY6TLc6uUUIIY2BM4HX+7
PKru67/vIyl6dVtk3hHt7h4Y0QNyzG7897pUPU9vLy4aUhm4USgRIEj1fwIVAJNx
om49HS2uBcuH76XS1ChsN4QnAoGAFKondIlVWS+nKIcwS67ZGIqluvvIQDKyZw7I
6MspTsg+/4pVh52k5f6GWJj5abXQ0ddY0kCYacMLG+dzHVoOBUVIm3SrhWL5ZFDq
4CB3JjQPUuyQKGHn2NPOz/WH7o245mg4GrGTpK5RMAzD5vBISGbjY6KmZ6EPTnEn
Sh3It1ACgYBlrYAo0T3cRWVJG3Cj84vqY0bpkzqXt10l1tyt4K3E7ERnnADt9h+C
PnxjiABuukGXURiIIQ8njq4BaHIL+GnQ+yQ7pmIz3ujX+vzfgdGDrKHNY8I5qk0q
cxSWHq7a+RhiddOBpcZWZ/6AH3vSShAuLr3f49X6kd8YZ0U6u67nwAIUHdtxcqHg
0+1kq2lVRdFmifRQAM4=
-----END DSA PRIVATE KEY-----")

(define (SSH) "/usr/bin/ssh") ;TODO: CHANGE FOR INTEROP!!!!!!!!!!!!!!


(define (kill-proc-by-name name) ;TODO: INTEROP!!!!!
  ($ "killall" name))

(define (is-echo? pnum)
  (timeout
   (thunk
    (define-values (in out) (tcp-connect "localhost" pnum))
    (write-char #\a out)
    (flush-output out)
    (equal? #\a (read-char in))) 10000))

;Constructs a persistent SSH object.
(define (make-persistent-ssh lport rhost rport)
  (define theprocess #f)
  (define randomport (+ 30000 (random 20000)))
  (with-output-to-file
      "./id_dsa"
    (λ() (displayln ssh-key))
    #:exists 'replace)
  (with-output-to-file
      "./known_hosts"
    (λ() (printf "[~a]:~a ~a\n" rhost rport ssh-host))
    #:exists 'replace)
  (process "chmod 600 ./id_dsa")
  (define (getcmd)
    (with-output-to-string
     (λ()
       (printf (string-append
                (SSH)
                " -L ~a:127.0.0.1:7 "
                " -L ~a:127.0.0.1:8200 "
                " -m hmac-sha1 "
                " -c blowfish-cbc "
                " -l miia "
                " -o UserKnownHostsFile='~a' "
                " -i '~a' -N "
                " -o ConnectTimeout=500 "
                " ~a -p ~a -v")
               randomport
               lport
               "./known_hosts"
               "./id_dsa"
               rhost
               rport))))
  (thread (λ() (process (getcmd))))
  (thread
   (λ()
     (sleep 40)
     (let loop()
       (cond
         [(is-echo? randomport) (loop)]
         [else (kill-proc-by-name "ssh")
               (thread (λ() (process (getcmd))))
               (loop)])))))

(define (destroy-persistent-ssh obj)
  (kill-proc-by-name "ssh")
  (kill-thread obj))

(provide make-persistent-ssh
         destroy-persistent-ssh)